﻿using System;
using System.Collections.Generic;
using System.Collections;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Net.Sockets;
using System.Net;
using System.Threading;

namespace IPresenter
{
    /// <summary>
    /// Main Form
    /// </summary>
    public partial class IPresenter : Form
    {
        /// <summary>
        /// Store distance of coordinate mouse between Form and desktop
        /// </summary>
        private Point pDelta;

        /// <summary>
        /// Object server
        /// </summary>
        private ServerIPresenter svServer;

        /// <summary>
        /// Object client
        /// </summary>
        private ClientIPresenter clClient;

        /// <summary>
        /// Object is used to draw string
        /// </summary>
        private IntroduceApplication inAppString;

        /// <summary>
        /// Get and set object IntroduceApplication
        /// </summary>
        public IntroduceApplication InAppString
        {
            get { return inAppString; }
            set { inAppString = value; }
        }

        /// <summary>
        /// Init 
        /// </summary>
        public IPresenter()
        {
            InitializeComponent();
            Bitmap bmpMain = Properties.Resources.MainForm;
            Bitmap bmpServer = Properties.Resources.server;
            Bitmap bmpClient = Properties.Resources.Client;
            Bitmap bmpNextSlide = Properties.Resources.next;
            Bitmap bmpPreviousSlide = Properties.Resources.previous;
            Bitmap bmpGoToSlide = Properties.Resources.gotoslide;
            Bitmap bmpFullScreen = Properties.Resources.fullscreen;
            Bitmap bmpEndFullScreen = Properties.Resources.endfullscreen;
            Bitmap bmpSearchPC = Properties.Resources.search;
            Bitmap bmpMinimize = Properties.Resources.Minimize;
            Bitmap bmpRefresh = Properties.Resources.Refresh;
            Bitmap bmpReset = Properties.Resources.reset;
            Bitmap bmpExit = Properties.Resources.exit;
            CustomizeControl.ChangeShapeControl(this, bmpMain);
            CustomizeControl.ChangeShapeControl(btn_server, bmpServer);
            CustomizeControl.ChangeShapeControl(btn_client, bmpClient);
            CustomizeControl.ChangeShapeControl(btnNextSlide, bmpNextSlide);
            CustomizeControl.ChangeShapeControl(btnPreviousSlide, bmpPreviousSlide);
            CustomizeControl.ChangeShapeControl(btnGoToSlide, bmpGoToSlide);
            CustomizeControl.ChangeShapeControl(btnFullScreen, bmpFullScreen);
            CustomizeControl.ChangeShapeControl(btnEndFullScreen, bmpEndFullScreen);
            CustomizeControl.ChangeShapeControl(btnSearchPC, bmpSearchPC);
            CustomizeControl.ChangeShapeControl(btnMinimize, bmpMinimize);
            CustomizeControl.ChangeShapeControl(btnExit, bmpExit);
            CustomizeControl.ChangeShapeControl(btnUpdate, bmpRefresh);
            CustomizeControl.ChangeShapeControl(btn_Reset, bmpReset);

            pDelta = new Point(0, 0);
            pnlMain.Visible = false;
            pnlServer.Visible = false;
            pnlClient.Visible = false;

            ImageList ilsFile = new ImageList();
            ilsFile.Images.Add(Properties.Resources.Document_Microsoft_PowerPoint);
            ilsFile.Images.Add(Properties.Resources.PowerPoint_icon);

            lvwFilePowerPoint.SmallImageList = ilsFile;
            lvwFilePowerPoint.LargeImageList = ilsFile;

            ImageList ilsComputer = new ImageList();
            ilsComputer.Images.Add(Properties.Resources.computer);

            lvwComputer.SmallImageList = ilsComputer;
            lvwComputer.LargeImageList = ilsComputer;

            ntfiMain.Text = "IPresenter";
            ntfiMain.ContextMenuStrip = ctmMain;
            ntfiMain.Icon = Properties.Resources.trayicon;
            lblFileName.Text = "No File is Choose";

            OptionIPresenter.Mode = OptionIPresenter.MODE_DEFAULT;
            OptionIPresenter.KindOfPresentation = OptionIPresenter.KIND_POWERPOINT;

            inAppString = new IntroduceApplication();
            PowerPointSupport.InitEvent();
            PowerPointSupport.UpdateFile = new PowerPointSupport.UpdateFileEventHandler(UpdateFilePowerPoint);

            Threads.ArrayThreads = new List<int>();
        }

        /// <summary>
        /// Update list of file powerpoint
        /// </summary>
        public void UpdateFilePowerPoint()
        {
            if (OptionIPresenter.Duty == OptionIPresenter.DUTY_SERVER)
            {
                pnlMain.Visible = false;
                pnlServer.Visible = true;
                pnlClient.Visible = false;
                lvwFilePowerPoint.Clear();
                foreach (string strFileName in PowerPointSupport.GetListOfFilePowerPoint())
                {
                    ListViewItem lvi = new ListViewItem();
                    lvi.ImageIndex = 1;
                    lvi.Text = strFileName;
                    lvwFilePowerPoint.Items.Add(lvi);
                }

                foreach (OpenOffice oo in OpenOfficeSupport.GetListOfOpenOffice())
                {
                    ListViewItem lvi = new ListViewItem();
                    lvi.ImageIndex = 0;
                    lvi.Text = oo.NameFile;
                    lvwFilePowerPoint.Items.Add(lvi);
                }
                if (lvwFilePowerPoint.Items.Count > 0)
                    lblFileName.Text = lvwFilePowerPoint.Items[0].Text;
                else
                    lblFileName.Text = "No File is choose";
            }
        }

        /// <summary>
        /// Init server.
        /// </summary>
        /// <param name="sender">Sender</param>
        /// <param name="e">EventArgs</param>
        private void btn_server_Click(object sender, EventArgs e)
        {
            Graphics graphics = this.CreateGraphics();
            graphics.DrawImage(Properties.Resources.MainForm, new Rectangle(0, 0, 422, 400), new Rectangle(0, 0, 422, 400), GraphicsUnit.Pixel);
            graphics.Dispose();
            pnlMain.Visible = false;
            pnlServer.Visible = true;
            pnlClient.Visible = false;
            svServer = new ServerIPresenter();
            svServer.Init();
            btn_server.Enabled = false;
            btn_client.Enabled = false;
            OptionIPresenter.Duty = OptionIPresenter.DUTY_SERVER;
            svServer.UpdateConnection = new ServerIPresenter.UpdateTypeConnection(UpdateNameConnection);
            tmUpdate.Enabled = false;
        }

        private void UpdateNameConnection(string nameConnection)
        {
            lbStatus.Text = nameConnection;
        }

        /// <summary>
        /// Init client
        /// </summary>
        /// <param name="sender">Sender</param>
        /// <param name="e">EventArgs</param>
        private void btn_client_Click(object sender, EventArgs e)
        {
            Graphics graphics = this.CreateGraphics();
            graphics.DrawImage(Properties.Resources.MainForm, new Rectangle(0, 0, 422, 400), new Rectangle(0, 0, 422, 400), GraphicsUnit.Pixel);
            graphics.Dispose();
            pnlMain.Visible = false;
            pnlServer.Visible = false;
            pnlClient.Visible = true;
            prgStatus.Visible = false;
            btn_client.Enabled = false;
            btn_server.Enabled = false;
            OptionIPresenter.Duty = OptionIPresenter.DUTY_CLIENT;
            tmUpdate.Enabled = false;
        }

        /// <summary>
        /// Execute mouse down
        /// </summary>
        /// <param name="sender">Sender</param>
        /// <param name="e">MouseEventArgs</param>
        private void Form1_MouseDown(object sender, MouseEventArgs e)
        {
            Point pMouse = new Point(e.X, e.Y);
            pDelta.X = PointToScreen(pMouse).X - DesktopLocation.X;
            pDelta.Y = PointToScreen(pMouse).Y - DesktopLocation.Y;
        }

        /// <summary>
        /// Execute mouse move
        /// </summary>
        /// <param name="sender">Sender</param>
        /// <param name="e">MouseEventArgs</param>
        private void Form1_MouseMove(object sender, MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Left)
            {
                Point pMouse = new Point(e.X, e.Y);
                Point tam = new Point();
                tam.X = PointToScreen(pMouse).X - pDelta.X;
                tam.Y = PointToScreen(pMouse).Y - pDelta.Y;
                DesktopLocation = tam;
            }
        }

        /// <summary>
        /// Get PC networks
        /// /// </summary>
        /// <param name="sender">Sender</param>
        /// <param name="e">EventArgs</param>
        private void btnSearchPC_Click(object sender, EventArgs e)
        {
            Threads.Start(this, Threads.CLIENT_PROGRESS_BAR);
        }

        /// <summary>
        /// Get list PC networks
        /// </summary>
        public void GetNetworkComputers()
        {
            NetworkSupport.GetNetworkComputers(prgStatus, lvwComputer);
        }

        /// <summary>
        /// Execute minimize
        /// </summary>
        /// <param name="sender">Sender</param>
        /// <param name="e">EvenArgs</param>
        private void btnMinimize_Click(object sender, EventArgs e)
        {
            this.WindowState = FormWindowState.Minimized;
        }

        /// <summary>
        /// Execute Notify icon
        /// </summary>
        /// <param name="sender">Sender</param>
        /// <param name="e">EventArgs</param>
        private void btnExit_Click(object sender, EventArgs e)
        {
            if (WindowState == FormWindowState.Normal)
            {
                WindowState = FormWindowState.Minimized;
                Hide();
            }
        }

        /// <summary>
        /// Execute click context menu strip(reopend)
        /// </summary>
        /// <param name="sender">Sender</param>
        /// <param name="e">EventArgs</param>
        private void reopeToolStripMenuItem_Click(object sender, EventArgs e)
        {
            Show();
            WindowState = FormWindowState.Normal;
        }

        /// <summary>
        /// Execute click context menu strip(reopend)
        /// </summary>
        /// <param name="sender">Sender</param>
        /// <param name="e">EventArgs</param>
        private void exitToolStripMenuItem_Click(object sender, EventArgs e)
        {
            Dispose();
        }

        /// <summary>
        /// Update file powerpoint
        /// </summary>
        /// <param name="sender">Sender</param>
        /// <param name="e">EventArgs</param>
        private void btnUpdate_Click(object sender, EventArgs e)
        {
            UpdateFilePowerPoint();
        }

        /// <summary>
        /// Execute previous slide
        /// </summary>
        /// <param name="sender">Sender</param>
        /// <param name="e">EventArgs</param>
        private void btnPreviousSlide_Click(object sender, EventArgs e)
        {
            if (OptionIPresenter.Mode == OptionIPresenter.MODE_DEFAULT)
            {
                NetworkSupport.SendMessageAscii(clClient.ClientDevice, PresentCommand.PREVIOUS_SLIDE);
            }
            else
            {
                if (OptionIPresenter.Mode == OptionIPresenter.MODE_EXTEND)
                {
                }
            }
        }

        /// <summary>
        /// Allow draw more times on screen in short time
        /// </summary>
        /// <param name="e"></param>
        protected override void OnPaintBackground(PaintEventArgs e)
        {
            base.OnPaintBackground(e);
        }

        /// <summary>
        /// Execute next slide
        /// </summary>
        /// <param name="sender">Sender</param>
        /// <param name="e">EventArgs</param>
        private void btnNextSlide_Click(object sender, EventArgs e)
        {
            try
            {
                if (OptionIPresenter.Mode == OptionIPresenter.MODE_DEFAULT)
                {
                    NetworkSupport.SendMessageAscii(clClient.ClientDevice, PresentCommand.NEXT_SLIDE);
                }
                else
                {
                    if (OptionIPresenter.Mode == OptionIPresenter.MODE_EXTEND)
                    {
                    }
                }
            }
            catch (Exception ex)
            {
                Logs.WriteErrorMessage(ex.Message);
            }
        }

        /// <summary>
        /// Execute Full Screen
        /// </summary>
        /// <param name="sender">Sender</param>
        /// <param name="e">EventArgs</param>
        private void btnFullScreen_Click(object sender, EventArgs e)
        {
            try
            {
                if (OptionIPresenter.Mode == OptionIPresenter.MODE_DEFAULT)
                {
                    NetworkSupport.SendMessageAscii(clClient.ClientDevice, PresentCommand.FULL_SCREEN);
                }
                else
                {
                    if (OptionIPresenter.Mode == OptionIPresenter.MODE_EXTEND)
                    {
                    }
                }
            }
            catch (Exception ex)
            {
                Logs.WriteErrorMessage(ex.Message);
            }
        }

        /// <summary>
        /// Execute end full screen
        /// </summary>
        /// <param name="sender">Sender</param>
        /// <param name="e">EventArgs</param>
        private void btnEndFullScreen_Click(object sender, EventArgs e)
        {
            try
            {
                if (OptionIPresenter.Mode == OptionIPresenter.MODE_DEFAULT)
                {
                    NetworkSupport.SendMessageAscii(clClient.ClientDevice, PresentCommand.END_FULL_SCREEN);
                }
                else
                {
                    if (OptionIPresenter.Mode == OptionIPresenter.MODE_EXTEND)
                    {
                    }
                }
            }
            catch (Exception ex)
            {
                Logs.WriteErrorMessage(ex.Message);
            }
        }

        /// <summary>
        /// Execute Reset
        /// </summary>
        public void Reset()
        {
            Threads.Dispose();
            pnlClient.Visible = false;
            lbStatus.Text = "Waiting Connect ........";
            lbConnect.Text = "Disconnect";
            lvwComputer.Clear();
            pnlServer.Visible = false;
            tmUpdate.Enabled = true;
            btn_server.Enabled = true;
            btn_client.Enabled = true;
            try
            {
                if (OptionIPresenter.Duty == OptionIPresenter.DUTY_SERVER)
                {
                    svServer.Dispose();
                }
                else
                {
                    if (OptionIPresenter.Duty == OptionIPresenter.DUTY_CLIENT)
                    {
                        clClient.Dispose();
                    }
                }
            }
            catch (Exception ex)
            {
                Logs.WriteErrorMessage(ex.Message);
            }
            finally
            {
                //Threads.Dispose();
            }
        }

        /// <summary>
        /// Execute reset
        /// </summary>
        /// <param name="sender">Sender</param>
        /// <param name="e">EventArgs</param>
        private void btn_Reset_Click(object sender, EventArgs e)
        {
            Reset();
        }

        /// <summary>
        /// Create connect from client to server
        /// </summary>
        /// <param name="sender">Sender</param>
        /// <param name="e">MouseEventArgs</param>
        private void lvwComputer_MouseDoubleClick(object sender, MouseEventArgs e)
        {
            try
            {
                clClient.Dispose();
                Threads.Dispose();
            }
            catch (Exception ex)
            {
                Logs.WriteErrorMessage(ex.Message);
            }
            try
            {
                this.Cursor = Cursors.WaitCursor;
                ListViewItem lvwi = lvwComputer.SelectedItems[0];
                NetworkSupport._SERVER_INFO_100 info = (NetworkSupport._SERVER_INFO_100)lvwi.Tag;
                clClient = new ClientIPresenter();
                bool blnResult = clClient.Init(info.sv100_name);
                if (blnResult == true)
                {
                    lbConnect.Text = "Connect";
                }
            }
            catch (Exception ex)
            {
                lbConnect.Text = "Have problem with connect";
                Logs.WriteErrorMessage(ex.Message);
            }

            this.Cursor = Cursors.Default;
        }

        /// <summary>
        /// Draw string on screen
        /// </summary>
        /// <param name="sender">Object cause event</param>
        /// <param name="e">Related information</param>
        private void tmUpdate_Tick(object sender, EventArgs e)
        {
            Graphics graphics = this.CreateGraphics();
            Bitmap bmp = new Bitmap(this.Width, 400);
            Graphics grVirtual = Graphics.FromImage(bmp);
            grVirtual.Clear(Color.Black);
            inAppString.Draw(grVirtual);
            graphics.DrawImage(bmp, new Point(0, 0));
            grVirtual.Dispose();
            graphics.Dispose();
        }

        private void btn_ConnectServer_Click(object sender, EventArgs e)
        {
            this.Cursor = Cursors.WaitCursor;
            try
            {
                clClient.Dispose();
            }
            catch (Exception ex)
            {
                Logs.WriteErrorMessage(ex.Message);
            }
            try
            {
                clClient = new ClientIPresenter();
                clClient.ClientDevice = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                IPEndPoint ipEndPoint = new IPEndPoint(IPAddress.Parse(txbIp.Text.ToString()), 3333);
                
                clClient.ClientDevice.Connect(ipEndPoint);
                clClient.FilesPresentation = new List<string>();
                lbConnect.Text = "Connect";
                HookProvider.RegisterHook();
                HookProvider.VirtualKeyDownDelegate = new HookProvider.GetKeyDownEventHandler(clClient.ReceiveKeyDown);
            }
            catch (Exception ex)
            {
                Logs.WriteErrorMessage(ex.Message);
            }

            this.Cursor = Cursors.Default;
        }
    }
}
